import json
import numpy as np

import networkx as nx  # 用于创建和操作图结构
import heapq          # 用于实现优先队列（Dijkstra算法）
from flow1 import TrafficGenerator
from switchesalgo import allocate_switches_with_es
from topo1 import build_hybrid_topology_shared_tor
from find_min_max_delay_path import optimize_reconfiguration
# from find_min_max_delay_path import find_min_max_delay_path
from topo1 import build_hybrid_topology_shared_tor

# 任务完成总延迟的计算

# 创建测试拓扑
G = build_hybrid_topology_shared_tor(num_tor=4)  # 从函数中获取拓扑
print("图的节点G.nodes:", G.nodes())
print("===========输出图的边===========")
print("图的边G.edges:", G.edges())
# 输出每条边的链路容量
# for u, v, data in G.edges(data=True):
#     print(f"链路 {u}→{v} 的容量为：{data['capacity']}")

# 从json文件中读取流量数据
with open('traffic_simulation.json', 'r') as f:
    data = json.load(f)
    # 输出时间为0.12时候的流量需求矩阵作为all_to_all
    for record in data:
        if record['timestamp'] == 0.12:
            all_to_all_list = record['matrix']
            # 转换为矩阵形式
            all_to_all = np.array(all_to_all_list)
            print(all_to_all)
        else:
            # 输出时间为5.19时候的流量需求矩阵作为brust
            if record['timestamp'] == 5.19:
                brust_list = record['matrix']
                brust = np.array(brust_list)
                print(brust)
print("输出的all_to_all流量需求矩阵为:", all_to_all)
print("输出的brust流量需求矩阵为:", brust)
hybrid_flow = brust
print("输出的混合流量需求矩阵为:", hybrid_flow)

# 根据流量需求矩阵获取通信对
all_to_all_dict = {(i, j): all_to_all[i][j] for i in range(all_to_all.shape[0]) for j in range(all_to_all.shape[1])}
hybrid_flow_dict = {(i, j): hybrid_flow[i][j] for i in range(hybrid_flow.shape[0]) for j in range(hybrid_flow.shape[1])}
# 获取all_to_all通信对
T_all_to_all = []
for pair, demand in all_to_all_dict.items():
    # print("pair:",pair)
    # print("demand:",demand)
    if demand > 0:
        T_all_to_all.append(pair)
for pair in T_all_to_all:
    print("pair:", pair)  # 输出的通信对的格式为（1,2），表示ToR1和ToR2

# 将键从 (i, j) 转换为 ("ToR{i}", "ToR{j}")
all_to_all_str_keys = {(f"ToR{i + 1}", f"ToR{j + 1}"): value for (i, j), value in all_to_all_dict.items()}
# print("D_str_keys:",D_str_keys)

# 将值从 numpy.ndarray 转换为浮点数
all_to_all_float_values = {k: float(v) for k, v in all_to_all_str_keys.items()}

# 生成通信对列表
T_all_to_all = [pair for pair, demand in all_to_all_float_values.items() if demand > 0]
print("生成all_to_all通信对列表", T_all_to_all)

# 生成all_to_all+brust通信对
T_hybird_flow = []
for pair, demand in hybrid_flow_dict.items():
    # print("pair:",pair)
    # print("demand:",demand)
    if demand > 0:
        T_hybird_flow.append(pair)
# for pair in T_hybird_flow:
#     print("pair:", pair)  # 输出的通信对的格式为（1,2），表示ToR1和ToR2

# 将键从 (i, j) 转换为 ("ToR{i}", "ToR{j}")
hybrid_str_keys = {(f"ToR{i + 1}", f"ToR{j + 1}"): value for (i, j), value in hybrid_flow_dict.items()}
# print("D_str_keys:",D_str_keys)

# 将值从 numpy.ndarray 转换为浮点数
hybrid_float_values = {k: float(v) for k, v in hybrid_str_keys.items()}

# 生成通信对列表
T_hybird_flow = [pair for pair, demand in hybrid_float_values.items() if demand > 0]
print("生成通信对列表", T_hybird_flow)

# 根据流量需求矩阵获取最优路径
S1,path_t = allocate_switches_with_es(G, T_all_to_all, all_to_all_float_values,{"tor1", "tor2","tor3","tor4"},{"os1", "os2","os3","os4"},18 )
# print("基本流量的最优路径为:",path_t)
print("\n基本流量的最优路径为:")
for pair, path in path_t.items():
    print(f"{pair} -> {path}")
S2,path_tt = allocate_switches_with_es(G, T_hybird_flow, hybrid_float_values,{"tor1", "tor2","tor3","tor4"},{"os1", "os2","os3","os4"}, 40)
# print("基本流量+突发流量的最优路径为:", path_tt)
print("\n基本流量+突发流量的最优路径为:")
for pair, path in path_tt.items():
    print(f"{pair} -> {path}")

# # 创建测试拓扑
# G = build_hybrid_topology_shared_tor(num_tor=4)  # 从函数中获取拓扑
# 执行优化算法
# reconfigured_paths, delays = optimize_reconfiguration(
#     hybrid_float_values, G, path_t, path_tt
# )
reconfigured_paths, delays ,no_delays= optimize_reconfiguration(
    hybrid_float_values, G, path_t, path_tt
)
# 输出结果
print("需要重构的通信对及电网络路径：")
for pair, path in reconfigured_paths.items():
    if path is not None:
        print(f"{pair}: 电网络路径 {path}，最大时延 {delays[pair]:.2f} ms")
    else:
        print(f"{pair}: 无可用电路径")

print("===========输出拓扑中所有路径的容量==================")

# # 输出每条边的链路容量
# for u, v, data in G.edges(data=True):
#     print(f"链路 {u}→{v} 的容量为：{data['capacity']}")
# print("===========输出拓扑中所有路径的容量==================")


print("不需要重构的通信对及路径")
for pair, path in path_t.items():
    # 如果通信对不在需要重构的通信对列表中（则保持原来的光链路）
    if pair not in reconfigured_paths:
        print(f"{pair}: 光网络路径 {path},最大时延 {no_delays[pair]:.2f}")
    else:
        print(f"不需要重构的{pair}：无可用路径")
        # # 获取每条路径的带宽
        # print(f"{pair}: 光网络路径 {path}")
        # for i in range(len(path) - 1):
        #     u, v = path[i], path[i + 1]
        #     # 获取每条边的链路容量
        #     link_capacity = G[u][v]['capacity']
        #     print(f"链路 {u}-{v} 的容量为 {link_capacity}")

# 定义光交换机的重构时延
optical_reconstruction_delay = 1 # 单位：ms 3DMEMS
# 不需要重构的通信对最大时延
max_no_pair_delay = 0
for pair, path in path_t.items():
    # 如果通信对不在需要重构的通信对列表中（则保持原来的光链路）
    if pair not in reconfigured_paths:
        # # 获取每条路径的带宽
        # print(f"{pair}: 光网络路径 {path}")
        no_pair_delay = no_delays[pair]
        if no_pair_delay > max_no_pair_delay:
            max_no_pair_delay = no_pair_delay
print("不需要重构的通信对最大时延为：",max_no_pair_delay)

# 需要重构的通信对最大时延
max_pair_delay = 0
# # 获取光链路的容量
# for u,v,
for pair, path in reconfigured_paths.items():
    if path is not None:
        pair_delay = delays[pair]
        # 如果在电链路的传输时间大于光链路的传输时间，则传输时间为电链路传输时间+在重构的网络中的传输时间
        if pair_delay > optical_reconstruction_delay:
            # 获取需要重构的通信对在电网路中传输的链路的最大最小链路的容量
            min_link_capacity = hybrid_float_values[pair] / pair_delay
            print(f"重构的通信对在电网路中传输的链路的最大最小链路的容量为{min_link_capacity}")
            total_pair_delay = (hybrid_float_values[pair]-min_link_capacity*optical_reconstruction_delay )/ 200 +optical_reconstruction_delay# 200为光链路的容量
            print(f"通信对{pair}在电网路中传输的时间{pair_delay}大于光链路的重构时间{optical_reconstruction_delay}，所以传输在电网络中的传输时间为重构时间{optical_reconstruction_delay}")
            print(f"通信对{pair}的通信量为{hybrid_float_values[pair]}，在电网络中的传输量为{min_link_capacity*optical_reconstruction_delay},在光网络中的剩余传输量为{(hybrid_float_values[pair]-min_link_capacity*optical_reconstruction_delay )}，所以在光网络中的传输时间为{(hybrid_float_values[pair]-min_link_capacity*optical_reconstruction_delay )/ 200}")
            print(f"总传输时间为{total_pair_delay}")
        else:
            # 在电链路传输完成的时间小于重构时间 则只需要在电链路中传输
            total_pair_delay = pair_delay
            print(f"通信对{pair}在电网路中传输的时间{pair_delay}小于光链路的重构时间{optical_reconstruction_delay}，所以传输时间为在电网络中的传输时间{total_pair_delay}")
        if total_pair_delay > max_pair_delay:
            max_pair_delay = total_pair_delay
    else:
        print(f"通信对{pair}在电网路中的传输路径为None")
print("需要重构的通信对最大时延为：",max_pair_delay)

if max_no_pair_delay > max_pair_delay:
    print("总时延为：",max_no_pair_delay)
else:
    print("总时延为：",max_pair_delay)

# 计算优化目标：总时延





